package com.ruicar.afs.cloud.apply.pre.loan.mq.receiver;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruicar.afs.cloud.apply.business.service.ApplyRecordDetailsService;
import com.ruicar.afs.cloud.apply.common.entity.*;
import com.ruicar.afs.cloud.apply.common.utils.ApplyConstants;
import com.ruicar.afs.cloud.apply.pre.loan.service.*;
import com.ruicar.afs.cloud.bizcommon.business.entity.FinCostDetails;
import com.ruicar.afs.cloud.bizcommon.business.entity.FinDiscountDetails;
import com.ruicar.afs.cloud.bizcommon.business.entity.FinFinancingItems;
import com.ruicar.afs.cloud.bizcommon.business.entity.FinRentAdjustDetails;
import com.ruicar.afs.cloud.bizcommon.business.service.ApplyCostDetailsService;
import com.ruicar.afs.cloud.bizcommon.business.service.ApplyDiscountDetailsService;
import com.ruicar.afs.cloud.bizcommon.business.service.ApplyFinancingItemsService;
import com.ruicar.afs.cloud.bizcommon.business.service.ApplyRentAdjustDetailsService;
import com.ruicar.afs.cloud.common.modules.afscorebusiness.enums.NoticeTypeEnum;
import com.ruicar.afs.cloud.common.modules.dto.mq.approve.ApplyResultInfoDto;
import com.ruicar.afs.cloud.common.modules.dto.mq.approve.ApproveInformDto;
import com.ruicar.afs.cloud.common.modules.dto.mq.approve.ApproveSpecialSubmitInfo;
import com.ruicar.afs.cloud.common.mq.rabbit.listener.AfsMqBizProcessor;
import com.ruicar.afs.cloud.common.mq.rabbit.message.MqTransCode;
import com.ruicar.afs.cloud.parameter.commom.enums.*;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
 * 资产变更-接收信审MQ
 *
 * @author 耿继辉
 */
@Slf4j
@AllArgsConstructor
@Component
@ConditionalOnProperty(prefix = "com.ruicar.afs.cloud.mq.rabbit", name = "enable")
public class ApplyAssertChangeDealProcessor implements AfsMqBizProcessor<ApproveSpecialSubmitInfo> {
    private final ApplyRecordDetailsService applyRecordDetailsService;
    private final ApplyOprRecordService applyOprRecordService;
    private final ApplyCustBaseInfoService applyCustBaseInfoService;
    private final ApplyModifyHistoryService applyModifyHistoryService;
    private final ApplyCostDetailsService applyCostDetailsService;
    private final ApplyFinancingItemsService applyFinancingItemsService;
    private final ApplyCarDetailsService applyCarDetailsService;
    private final ApplyDiscountDetailsService applyDiscountDetailsService;
    private final ApplyRentAdjustDetailsService applyRentAdjustDetailsService;
    private final ApplyRemindDetailsService applyRemindDetailsService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean processMessage(ApproveSpecialSubmitInfo entity) {
        log.info("接收资产变更返回报文体：{}", entity);
        if (ObjectUtil.isNotNull(entity)) {
            if (ObjectUtil.isNotNull(entity.getResultInfoDto())) {
                //成功,分为入库成功，审批成功结果通知
                if (ResultBooleanEnum.TRUE.getCode().equals(entity.getResultInfoDto().getResult())) {
                    this.successMessage(entity.getResultInfoDto(), entity.getApproveInformDto());
                } else if (ResultBooleanEnum.FALSE.getCode().equals(entity.getResultInfoDto().getResult())) {
                    //失败-入库失败
                    this.failedMessage(entity.getResultInfoDto());
                }
            } else if (ObjectUtil.isNotNull(entity.getApproveInformDto())) {
                //记录资产变更审批记录
                this.saveApproveData(entity.getApproveInformDto());
            }
        }
        return true;
    }

    @Override
    public MqTransCode getCode() {
        return MqTransCode.AFS_POS_APPLY_CASE_CTM_ASSETS_RECONSIDER;
    }

    @Override
    public boolean reQueueOnFail() {
        return false;
    }

    /**
     * 返回成功，更新状态
     *
     * @param entity 审批通知
     */
    public void successMessage(ApplyResultInfoDto entity, ApproveInformDto approveInformDto) {
        //如果是入库成功通知
        if (NoticeTypeEnum.FALLLIBRARY.getCode().equals(entity.getNoticeType())) {
            log.info("================申请编号:" + entity.getApplyNo() + ",信审已入库成功===================");
        }
    }

    /**
     * @param entity 审批通知
     */
    public void failedMessage(ApplyResultInfoDto entity) {
        //如果是入库失败通知
        if (NoticeTypeEnum.FALLLIBRARY.getCode().equals(entity.getNoticeType())) {
            log.info("--申请编号:" + entity.getApplyNo() + ",信审接收报文失败");
        }
    }


    /**
     * 资产变更保存操作表/审批记录表数据
     *
     * @param entity 审批通知
     */
    public void saveApproveData(ApproveInformDto entity) {
        String applyNo = entity.getApplyNo();
        ApplyCustBaseInfo mainCustBaseInfo = this.applyCustBaseInfoService.getCustBaseInfo(applyNo, ApplyConstants.PRINCIPAL_BORROWER);
        ApplyCustBaseInfo commonBaseInfo = this.applyCustBaseInfoService.getCustBaseInfo(applyNo, ApplyConstants.COMMON_BORROWER);
        ApplyCustBaseInfo guarantorCustBaseInfo = this.applyCustBaseInfoService.getCustBaseInfo(applyNo, ApplyConstants.GUARANTOR);
        //通过//取消/拒绝得审批时间
        Date occurrenceTime = entity.getOccurrenceTime();
        //审批记录
        WorkflowRecordDetails applyRecordDetails = new WorkflowRecordDetails();
        //查出操作为资产变更的记录,存在就更新
        List<ApplyOprRecord> list = this.applyOprRecordService.list(Wrappers.<ApplyOprRecord>query().lambda().
                eq(StringUtil.isNotEmpty(applyNo), ApplyOprRecord::getApplyNo, applyNo)
                .eq(ApplyOprRecord::getApplyType, String.valueOf(OrderOprType.ASSERTCHANGE)));
        ApplyOprRecord oprRecord = list.get(list.size() - 1);
        if (ObjectUtil.isNotNull(oprRecord)) {
            oprRecord.setApplyNo(applyNo);
            //资产变更会存操作记录，从操作记录表中查询该条数据，然后将Id存为审批记录表得业务编号
            applyRecordDetails.setBusinessNo(String.valueOf(oprRecord.getId()));
            oprRecord.setApplyType(OrderOprType.ASSERTCHANGE);
            oprRecord.setApplyReason(entity.getApproveReason());
            //客户信息
            if (ObjectUtil.isNotNull(mainCustBaseInfo)) {
                oprRecord.setCustName(mainCustBaseInfo.getCustName());
                oprRecord.setCertNo(mainCustBaseInfo.getCertNo());
            }
        }
        applyRecordDetails.setProcessName(entity.getApproveType());
        //如果是待审核/暂停，就更新为待审核
        if (AProveBusinessTypeEnum.PENDING_REVIEW.getCode().equals(entity.getApproveType())) {
            //审批类型：待审核
            applyRecordDetails.setApproveResult(entity.getApproveType());
            oprRecord.setApplyStatus(AssetChangeEnums.PENDING.getCode());
            log.info("资产变更-待审核:{}", applyNo);
        } else if (AProveBusinessTypeEnum.PARSE.getCode().equals(entity.getApproveType())) {
            //暂停-待审核
            applyRecordDetails.setApproveResult(entity.getApproveType());
            oprRecord.setApplyStatus(AssetChangeEnums.PENDING.getCode());
            log.info("资产变更-暂停(待审核):{}", applyNo);
        } else if (AProveBusinessTypeEnum.SUGGEST_CHECK.getCode().equals(entity.getApproveType())) {
            //建议核准：就更新为审核中
            applyRecordDetails.setApproveResult(entity.getApproveType());
            oprRecord.setApplyStatus(AssetChangeEnums.AUDIT.getCode());
            log.info("资产变更-建议核准(审核中):{}", applyNo);
        } else if (AProveBusinessTypeEnum.SUGGEST_REJECT.getCode().equals(entity.getApproveType())) {
            //建议拒绝：就更新为:-审核中
            applyRecordDetails.setApproveResult(entity.getApproveType());
            oprRecord.setApplyStatus(AssetChangeEnums.AUDIT.getCode());
            oprRecord.setApproveDate(occurrenceTime);
            log.info("资产变更-建议拒绝(审核中):{}", applyNo);
        } else if (AProveBusinessTypeEnum.BACK.getCode().equals(entity.getApproveType())) {
            //修订暂停，就更新为：-修订暂停
            applyRecordDetails.setApproveResult(entity.getApproveType());
            if (StringUtil.isNotEmpty(entity.getStageId())) {
                //流程id
                oprRecord.setProcessId(entity.getStageId());
                oprRecord.setApproveRemarks(entity.getLeaveMessage());
            }
            //保存资产变更退回留言
            this.saveRemind(entity,oprRecord.getId());
            log.info("{},资产变更-修订暂停-审批留言保存", applyNo);
            oprRecord.setApplyStatus(AssetChangeEnums.REVISIONSUSPENSION.getCode());
            log.info("资产变更-修订暂停{}", applyNo);
        } else if (AProveBusinessTypeEnum.SUGGEST_CANCEL.getCode().equals(entity.getApproveType())) {
            oprRecord.setApproveDate(new Date());
            //撤消，就更新为：-取消
            applyRecordDetails.setApproveResult(entity.getApproveSuggest());
            applyRecordDetails.setApproveDate(new Date());
            oprRecord.setApplyStatus(AssetChangeEnums.CHANGECANCELLATION.getCode());
            log.info("资产变更-撤销(取消)：{}", applyNo);
        } else if (AProveBusinessTypeEnum.SUGGEST_CHECK_FINAL.getCode().equals(entity.getApproveType())) {
            //核准，就更新为：-通过
            applyRecordDetails.setApproveDate(occurrenceTime);
            applyRecordDetails.setApproveResult(entity.getApproveType());
            oprRecord.setApplyStatus(AssetChangeEnums.CHANGEPASS.getCode());
            log.info("资产变更-核准(通过)：{}", applyNo);
            //更新资产变更成功时间
            oprRecord.setApproveDate(occurrenceTime);
            //资产变更核准通过，客户信息更新is_lock  = 1
            if (ObjectUtil.isNotNull(mainCustBaseInfo)) {
                mainCustBaseInfo.setIsLock(WhetherEnum.YES.getIndex());
                this.applyCustBaseInfoService.updateById(mainCustBaseInfo);
                log.info("资产变更-已核准，主借人信息锁定");
            }
            if (ObjectUtil.isNotNull(commonBaseInfo)) {
                commonBaseInfo.setIsLock(WhetherEnum.YES.getIndex());
                this.applyCustBaseInfoService.updateById(commonBaseInfo);
            }
            if (ObjectUtil.isNotNull(guarantorCustBaseInfo)) {
                guarantorCustBaseInfo.setIsLock(WhetherEnum.YES.getIndex());
                this.applyCustBaseInfoService.updateById(guarantorCustBaseInfo);
                log.info("资产变更-已核准，担保人信息锁定");
            }
            this.replaceAssertChangeParams(applyNo);// 覆盖数据
        } else if (AProveBusinessTypeEnum.SUGGEST_REJECT_FINAL.getCode().equals(entity.getApproveType())) {
            oprRecord.setApproveDate(new Date());
            //拒绝：-拒绝-回滚至变更前
            applyRecordDetails.setApproveDate(new Date());
            applyRecordDetails.setApproveResult(entity.getApproveType());
            oprRecord.setApplyStatus(AssetChangeEnums.CHANGEREFUSAL.getCode());
            log.info("资产变更-拒绝：{}", applyNo);
        }
        //保存
        applyRecordDetails.setBusinessType(String.valueOf(OrderOprType.ASSERTCHANGE));
        applyRecordDetails.setCreateBy(mainCustBaseInfo.getCreateBy());
        this.applyOprRecordService.updateById(oprRecord);
        log.info(applyNo + "====================资产变更操作记录已入库====================");
        this.applyRecordDetailsService.save(applyRecordDetails);
        log.info(applyNo + "====================资产变更审批记录已入库====================");
    }

    /**
     * 保存留言
     *
     * @param entity
     */
    public void saveRemind(ApproveInformDto entity,Long id) {
        ApplyRemindDetails applyRemindDetails = new ApplyRemindDetails();
        applyRemindDetails.setRemindId(id);
        applyRemindDetails.setBusinessType(String.valueOf(OrderOprType.ASSERTCHANGE));
        applyRemindDetails.setApplyNo(entity.getApplyNo());
        //applyRemindDetails.setMsgContent(entity.getApproveSuggest());
        applyRemindDetails.setMsgCode(entity.getApproveSuggest());
        applyRemindDetails.setMsgContent(entity.getLeaveMessage());// add by sijun.yu 2020-10-10 修订回复留言
        applyRemindDetails.setIsSelf(WhetherEnum.No.getIndex());
        applyRemindDetails.setRemindType(entity.getApproveType());
        applyRemindDetails.setCreateBy("审批专员");
        applyRemindDetails.setCreateTime(entity.getOccurrenceTime());
        this.applyRemindDetailsService.save(applyRemindDetails);
    }

    /**
     * 资产变更-覆盖数据
     *
     * @param applyNo
     */
    public void replaceAssertChangeParams(String applyNo) {

        // 获取变更前数据留痕
        ApplyModifyHistory modifyHistory = this.applyModifyHistoryService.getModifyHistoryByApplyNo(applyNo);
        if (ObjectUtil.isNotNull(modifyHistory)) {
            JSONObject approveContent = JSONObject.parseObject(modifyHistory.getBodyContent());
            // 车辆信息
            List<ApplyCarDetails> carDetailsList = approveContent.getJSONArray("finCarDetailsList").toJavaList(ApplyCarDetails.class);
            if (CollectionUtil.isNotEmpty(carDetailsList)) {
                carDetailsList.forEach(applyCarDetailsService::updateById);
            }
            // 融资信息
            FinCostDetails addDetails = applyCostDetailsService.getApplyCostDetails(applyNo, CostType.AFFIXAMT.getIndex());
            List<FinCostDetails> finCostDetailsList = approveContent.getJSONArray("finCostDetailsList").toJavaList(FinCostDetails.class);
            if (CollectionUtil.isNotEmpty(finCostDetailsList)) {
                if (finCostDetailsList.size() == 1 && addDetails != null) {
                    applyCostDetailsService.removeById(addDetails.getId());
                }
                finCostDetailsList.forEach(x -> {
                    if (CostType.CARAMT.getIndex().equals(x.getCostType())) {
                        applyCostDetailsService.updateById(x);
                    } else if (CostType.CARAMT.getIndex().equals(x.getCostType())) {
                        if (addDetails != null) {
                            applyCostDetailsService.updateById(x);
                        } else {
                            applyCostDetailsService.save(x);
                        }
                    }
                });
            }
            // 租金调整
            List<FinRentAdjustDetails> rentList = applyRentAdjustDetailsService.getRentAdjustDetails(applyNo);
            if (CollectionUtil.isNotEmpty(rentList)) {
                rentList.forEach(x -> {
                    applyRentAdjustDetailsService.removeById(x.getId());
                });
            }
            List<FinRentAdjustDetails> finRentAdjustDetailsList = approveContent.getJSONArray("finRentAdjustDetailsList").toJavaList(FinRentAdjustDetails.class);
            if (CollectionUtil.isNotEmpty(finRentAdjustDetailsList)) {
                finRentAdjustDetailsList.forEach(applyRentAdjustDetailsService::save);
            }
            // 融资项
            List<FinFinancingItems> itemsList = applyFinancingItemsService.getApplyFinancingItemsList(applyNo);
            if (CollectionUtil.isNotEmpty(itemsList)) {
                itemsList.forEach(x -> {
                    applyFinancingItemsService.removeById(x.getId());
                });
            }
            List<FinFinancingItems> finFinancingItemsList = approveContent.getJSONArray("finFinancingItemsList").toJavaList(FinFinancingItems.class);
            if (CollectionUtil.isNotEmpty(finFinancingItemsList)) {
                finFinancingItemsList.forEach(x -> {
                    applyFinancingItemsService.save(x);
                    if (x.getSonList() != null && x.getSonList().size() > 0) {
                        x.getSonList().forEach(y -> {
                            applyFinancingItemsService.save(y);
                        });
                    }
                });
            }
            // 贴息项
            List<FinDiscountDetails> discountList = applyDiscountDetailsService.getDiscountDetailsList(applyNo);
            if (CollectionUtil.isNotEmpty(discountList)) {
                discountList.forEach(x -> {
                    applyDiscountDetailsService.removeById(x.getId());
                });
            }
            List<FinDiscountDetails> finDiscountDetailsList = approveContent.getJSONArray("finDiscountDetailsList").toJavaList(FinDiscountDetails.class);
            if (CollectionUtil.isNotEmpty(finDiscountDetailsList)) {
                finDiscountDetailsList.forEach(applyDiscountDetailsService::save);
            }
        }
    }


}
